from django.db import models
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.db.models import Sum, Avg, Max, Min, F
from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from django.contrib.auth.models import PermissionsMixin
from django.db import models

# 替代方案（假设使用Django 4.x及以上版本）
from django.core.files.storage import default_storage

# Create your models here.
# 用户表


# 用户表
class UserData(models.Model):
    name = models.CharField(max_length=100, verbose_name='用户名')
    password = models.CharField(max_length=100, verbose_name='用户密码')

    def __str__(self):
        return self.name


#
#
# 数据管理员表
# class DataAdmin(models.Model):
#     name = models.CharField(max_length=100, verbose_name='管理员名称')
#     password = models.CharField(max_length=100, verbose_name='管理员密码')
#
#     def __str__(self):
#         return self.name


#
"""
方法三
"""


class Product(models.Model):  # 定义Product模型类
    product_id = models.CharField(primary_key=True,max_length=255)  # 自定义的非自动递增主键字段
    product_name = models.CharField(max_length=255)  # 定义产品名称字段，最大长度为255字符
    price = models.DecimalField(max_digits=10, decimal_places=2)  # 定义价格字段，最多10位数字，其中2位小数
    category = models.CharField(max_length=100)  # 定义类别字段，最大长度为100字符
    sales_volume = models.IntegerField()  # 定义销售量字段，整数类型
    brand = models.CharField(max_length=100)  # 定义品牌字段，最大长度为100字符
    rating = models.FloatField()  # 定义评分字段，浮点数类型
    store = models.CharField(max_length=100)  # 定义店铺字段，最大长度为100字符

    def __str__(self):
        return self.product_name  # 返回产品名称作为对象的字符串表示


class ProductSales(models.Model):  # 定义ProductSales模型类
    product_id = models.CharField(primary_key=True,max_length=255)  # 商品ID，主键
    product_name = models.CharField(max_length=255)  # 商品名称
    sales_volume = models.IntegerField()  # 商品销量
    category = models.CharField(max_length=100)  # 商品类别
    brand = models.CharField(max_length=100)  # 商品品牌
    rating = models.FloatField()  # 商品评分
    store = models.CharField(max_length=100)  # 商品店铺

    class Meta:
        db_table = 'product_sales'  # 指定数据库表名为product_sales

    def __str__(self):
        return f"{self.product_name} - {self.sales_volume}"  # 返回商品名称和销量作为对象的字符串表示


# 连接信号以监听Product表的变化
@receiver(post_save, sender=Product)  # 当Product实例保存后触发
def sync_product_sales_on_save(sender, instance, **kwargs):
    ProductSales.objects.update_or_create(  # 更新或创建ProductSales记录
        product_id=instance.product_id,
        defaults={
            'product_name': instance.product_name,  # 设置商品名称
            'sales_volume': instance.sales_volume,  # 设置商品销量
            'category': instance.category,  # 设置商品类别
            'brand': instance.brand,  # 设置商品品牌
            'rating': instance.rating,  # 设置商品评分
            'store': instance.store,  # 设置商品店铺
        }
    )


@receiver(post_delete, sender=Product)  # 当Product实例删除后触发
def sync_product_sales_on_delete(sender, instance, **kwargs):
    ProductSales.objects.filter(product_id=instance.product_id).delete()  # 删除对应的ProductSales记录


# 示例汇总模型保持不变
class BrandSummary(models.Model):  # 定义BrandSummary模型类
    brand = models.CharField(max_length=100, primary_key=True)  # 定义品牌字段，最大长度为100字符，作为主键
    total_sales_volume = models.IntegerField(null=True, blank=True)  # 定义总销售量字段，整数类型
    avg_rating = models.FloatField(null=True, blank=True)  # 定义平均评分字段，浮点数类型
    avg_price = models.DecimalField(max_digits=10, decimal_places=2,null=True, blank=True)  # 定义平均价格字段，最多10位数字，其中2位小数
    avg_sales_volume_per_product = models.IntegerField(null=True, blank=True,)  # 定义每个产品的平均销售量字段，整数类型
    max_price = models.DecimalField(max_digits=10, decimal_places=2,null=True, blank=True)  # 定义最高价格字段，最多10位数字，其中2位小数
    min_price = models.DecimalField(max_digits=10, decimal_places=2,null=True, blank=True)  # 定义最低价格字段，最多10位数字，其中2位小数

    @classmethod
    def create_or_update(cls):  # 创建或更新BrandSummary记录的方法
        summaries = (
            Product.objects.values('brand')  # 获取所有品牌
            .annotate(
                total_sales_volume=Sum('sales_volume'),  # 计算总销售量
                avg_rating=Avg('rating'),  # 计算平均评分
                avg_price=Avg('price'),  # 计算平均价格
                avg_sales_volume_per_product=Avg(F('sales_volume')),  # 计算每个产品的平均销售量
                max_price=Max('price'),  # 计算最高价格
                min_price=Min('price')  # 计算最低价格
            )
        )
        for summary in summaries:  # 遍历每个品牌的汇总数据
            obj, created = cls.objects.update_or_create(  # 更新或创建BrandSummary记录
                brand=summary['brand'],
                defaults={
                    'total_sales_volume': summary['total_sales_volume'],  # 设置总销售量
                    'avg_rating': summary['avg_rating'],  # 设置平均评分
                    'avg_price': summary['avg_price'],  # 设置平均价格
                    'avg_sales_volume_per_product': summary['avg_sales_volume_per_product'],  # 设置每个产品的平均销售量
                    'max_price': summary['max_price'],  # 设置最高价格
                    'min_price': summary['min_price'],  # 设置最低价格
                }
            )


class CategorySummary(models.Model):  # 定义CategorySummary模型类
    category = models.CharField(max_length=100, primary_key=True)  # 定义类别字段，最大长度为100字符，作为主键
    total_sales_volume = models.IntegerField(null=True, blank=True)  # 定义总销售量字段，整数类型
    avg_rating = models.FloatField(null=True, blank=True)  # 定义平均评分字段，浮点数类型
    avg_price = models.DecimalField(max_digits=10, decimal_places=2,null=True, blank=True)  # 定义平均价格字段，最多10位数字，其中2位小数
    avg_sales_volume_per_product = models.IntegerField(null=True, blank=True)  # 定义每个产品的平均销售量字段，整数类型
    max_price = models.DecimalField(max_digits=10, decimal_places=2,null=True, blank=True)  # 定义最高价格字段，最多10位数字，其中2位小数
    min_price = models.DecimalField(max_digits=10, decimal_places=2,null=True, blank=True)  # 定义最低价格字段，最多10位数字，其中2位小数

    @classmethod
    def create_or_update(cls):  # 创建或更新CategorySummary记录的方法
        summaries = (
            Product.objects.values('category')  # 获取所有类别
            .annotate(
                total_sales_volume=Sum('sales_volume'),  # 计算总销售量
                avg_rating=Avg('rating'),  # 计算平均评分
                avg_price=Avg('price'),  # 计算平均价格
                avg_sales_volume_per_product=Avg(F('sales_volume')),  # 计算每个产品的平均销售量
                max_price=Max('price'),  # 计算最高价格
                min_price=Min('price')  # 计算最低价格
            )
        )
        for summary in summaries:  # 遍历每个类别的汇总数据
            obj, created = cls.objects.update_or_create(  # 更新或创建CategorySummary记录
                category=summary['category'],
                defaults={
                    'total_sales_volume': summary['total_sales_volume'],  # 设置总销售量
                    'avg_rating': summary['avg_rating'],  # 设置平均评分
                    'avg_price': summary['avg_price'],  # 设置平均价格
                    'avg_sales_volume_per_product': summary['avg_sales_volume_per_product'],  # 设置每个产品的平均销售量
                    'max_price': summary['max_price'],  # 设置最高价格
                    'min_price': summary['min_price'],  # 设置最低价格
                }
            )


class StoreSummary(models.Model):  # 定义StoreSummary模型类
    store = models.CharField(max_length=100, primary_key=True)  # 定义店铺字段，最大长度为100字符，作为主键
    total_sales_volume = models.IntegerField(null=True, blank=True)  # 定义总销售量字段，整数类型
    avg_rating = models.FloatField(null=True, blank=True)  # 定义平均评分字段，浮点数类型
    avg_price = models.DecimalField(max_digits=10, decimal_places=2,null=True, blank=True)  # 定义平均价格字段，最多10位数字，其中2位小数
    avg_sales_volume_per_product = models.IntegerField(null=True, blank=True)  # 定义每个产品的平均销售量字段，整数类型
    max_price = models.DecimalField(max_digits=10, decimal_places=2,null=True, blank=True)  # 定义最高价格字段，最多10位数字，其中2位小数
    min_price = models.DecimalField(max_digits=10, decimal_places=2,null=True, blank=True)  # 定义最低价格字段，最多10位数字，其中2位小数

    @classmethod
    def create_or_update(cls):  # 创建或更新StoreSummary记录的方法
        summaries = (
            Product.objects.values('store')  # 获取所有店铺
            .annotate(
                total_sales_volume=Sum('sales_volume'),  # 计算总销售量
                avg_rating=Avg('rating'),  # 计算平均评分
                avg_price=Avg('price'),  # 计算平均价格
                avg_sales_volume_per_product=Avg(F('sales_volume')),  # 计算每个产品的平均销售量
                max_price=Max('price'),  # 计算最高价格
                min_price=Min('price')  # 计算最低价格
            )
        )
        for summary in summaries:  # 遍历每个店铺的汇总数据
            obj, created = cls.objects.update_or_create(  # 更新或创建StoreSummary记录
                store=summary['store'],
                defaults={
                    'total_sales_volume': summary['total_sales_volume'],  # 设置总销售量
                    'avg_rating': summary['avg_rating'],  # 设置平均评分
                    'avg_price': summary['avg_price'],  # 设置平均价格
                    'avg_sales_volume_per_product': summary['avg_sales_volume_per_product'],  # 设置每个产品的平均销售量
                    'max_price': summary['max_price'],  # 设置最高价格
                    'min_price': summary['min_price'],  # 设置最低价格
                }
            )


class RatingGroupSummary(models.Model):  # 定义RatingGroupSummary模型类
    rating_group = models.CharField(max_length=10, primary_key=True)  # 定义评分组字段，最大长度为10字符，作为主键
    total_sales_volume = models.IntegerField(null=True, blank=True)  # 定义总销售量字段，整数类型
    avg_rating = models.FloatField(null=True, blank=True)  # 定义平均评分字段，浮点数类型
    avg_price = models.DecimalField(max_digits=10, decimal_places=2,null=True, blank=True)  # 定义平均价格字段，最多10位数字，其中2位小数
    avg_sales_volume_per_product = models.IntegerField(null=True, blank=True)  # 定义每个产品的平均销售量字段，整数类型
    max_price = models.DecimalField(max_digits=10, decimal_places=2,null=True, blank=True)  # 定义最高价格字段，最多10位数字，其中2位小数
    min_price = models.DecimalField(max_digits=10, decimal_places=2,null=True, blank=True)  # 定义最低价格字段，最多10位数字，其中2位小数

    @classmethod
    def create_or_update(cls):  # 创建或更新RatingGroupSummary记录的方法
        rating_groups = [
            {'name': '98-100', 'min_rating': 98, 'max_rating': 100},  # 定义评分组98-100
            {'name': '96-98', 'min_rating': 96, 'max_rating': 98},  # 定义评分组96-98
            {'name': '94-96', 'min_rating': 94, 'max_rating': 96},  # 定义评分组94-96
            {'name': '0-94', 'min_rating': 0, 'max_rating':94} #定义评分分组94以下
        ]

        for group in rating_groups:  # 遍历每个评分组
            products_in_group = Product.objects.filter(
                rating__gte=group['min_rating'],
                rating__lte=group['max_rating']
            ).aggregate(
                total_sales_volume=Sum('sales_volume'),  # 计算总销售量
                avg_rating=Avg('rating'),  # 计算平均评分
                avg_price=Avg('price'),  # 计算平均价格
                avg_sales_volume_per_product=Avg(F('sales_volume')),  # 计算每个产品的平均销售量
                max_price=Max('price'),  # 计算最高价格
                min_price=Min('price')  # 计算最低价格
            )

            obj, created = cls.objects.update_or_create(  # 更新或创建RatingGroupSummary记录
                rating_group=group['name'],
                defaults={
                    **products_in_group,  # 使用聚合结果作为默认值
                }
            )


# 连接信号以监听Product表的变化
@receiver(post_save, sender=Product)  # 当Product实例保存后触发
def update_summaries_and_sync_product_sales_on_save(sender, instance, **kwargs):
    BrandSummary.create_or_update()  # 更新BrandSummary记录
    CategorySummary.create_or_update()  # 更新CategorySummary记录
    StoreSummary.create_or_update()  # 更新StoreSummary记录
    RatingGroupSummary.create_or_update()  # 更新RatingGroupSummary记录
    ProductSales.objects.update_or_create(  # 更新或创建ProductSales记录
        product_id=instance.product_id,
        defaults={
            'product_name': instance.product_name,  # 设置商品名称
            'sales_volume': instance.sales_volume,  # 设置商品销量
            'category': instance.category,  # 设置商品类别
            'brand': instance.brand,  # 设置商品品牌
            'rating': instance.rating,  # 设置商品评分
            'store': instance.store,  # 设置商品店铺
        }
    )


@receiver(post_delete, sender=Product)  # 当Product实例删除后触发
def update_summaries_and_sync_product_sales_on_delete(sender, instance, **kwargs):
    BrandSummary.create_or_update()  # 更新BrandSummary记录
    CategorySummary.create_or_update()  # 更新CategorySummary记录
    StoreSummary.create_or_update()  # 更新StoreSummary记录
    RatingGroupSummary.create_or_update()  # 更新RatingGroupSummary记录
    ProductSales.objects.filter(product_id=instance.product_id).delete()  # 删除对应的ProductSales记录


# 销售详情表
"""方法二"""

#
# # 1.类别表
# class Category(models.Model):
#     name = models.CharField(max_length=100)
#     num_products = models.IntegerField(default=0)  # 类别下的产品数量
#     total_sales = models.IntegerField(default=0)  # 类别下的累计销售数量
#
#     def __str__(self):
#         return self.name
#
#
# # 2.品牌表
# class Brand(models.Model):
#     name = models.CharField(max_length=100)
#     num_products = models.IntegerField(default=0)  # 品牌下的产品数量
#     total_sales = models.IntegerField(default=0)  # 品牌下的累计销售数量
#
#     def __str__(self):
#         return self.name
#
#
# # 3.商品详情表
# from django.db import models, transaction
#
#
# class Product(models.Model):
#     product_id = models.CharField(max_length=100, primary_key=True)
#     category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')
#     brand = models.ForeignKey(Brand, on_delete=models.CASCADE, related_name='products')
#     name = models.CharField(max_length=100)
#     price = models.DecimalField(max_digits=10, decimal_places=2)
#
#     # store = models.ForeignKey(Store, on_delete=models.CASCADE, related_name='products')
#
#     def __str__(self):
#         return self.name
#
#
# # 4.商品销售表
# class SalesDetail(models.Model):
#     sale_id = models.AutoField(primary_key=True)
#     product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='sales')
#     quantity = models.IntegerField()  # 单次销售的数量
#     cumulative_quantity = models.IntegerField(default=0)  # 累计销售数量
#
#     # def save(self, *args, **kwargs):
#     #     # 在保存时更新产品的累计销售数量
#     #     if self.pk is None:  # 只在创建新记录时更新
#     #         self.cumulative_quantity += self.quantity
#     #         self.product.brand.total_sales += self.quantity
#     #         self.product.category.total_sales += self.quantity
#     #         self.product.brand.save()
#     #         self.product.category.save()
#     #     super().save(*args, **kwargs)
#
#     def __str__(self):
#         return f"Sale #{self.sale_id} - {self.product.name}"
#
#
# # # 5.店铺表
# # class Store(models.Model):
# #     store_id = models.AutoField(primary_key=True)
# #     name = models.CharField(max_length=100)
# #     positive_reviews = models.IntegerField(default=0)  # 店铺好评
# #
# #     def __str__(self):
# #         return self.name
#
#
# # 商品好评
# class CustomerReview(models.Model):
#     review_id = models.AutoField(primary_key=True)
#     product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='reviews')
#     rating = models.IntegerField()  # 假设评分是整数，范围为1到5
#
#     def __str__(self):
#         return f"Review #{self.review_id} on {self.product.name}"
#

"""方法一"""
# class SalesDetail(models.Model):
#     # 销售ID，作为主键使用，唯一标识每一次销售
#     sale_id = models.AutoField(primary_key=True)
#     # 产品外键，关联到Product模型， CASCADE确保当关联的产品被删除时，相应的销售记录也会被删除
#     product = models.ForeignKey('Product', on_delete=models.CASCADE, related_name='sales')
#     # 销售数量，表示销售出去的产品数量
#     quantity = models.IntegerField()
#
#     def __str__(self):
#         return f"Sale #{self.sale_id} - {self.product.name}"
#
#
# # 商品表
# class Product(models.Model):
#     # 商品ID，作为主键使用，唯一标识每一个商品
#     product_id = models.CharField(max_length=100,primary_key=True)
#     # 商品分类，外键关联到Category模型，CASCADE确保当关联的分类被删除时，相应的商品也会被删除
#     category = models.ForeignKey('Category', on_delete=models.CASCADE)
#     # 商品品牌，外键关联到Brand模型，CASCADE确保当关联的品牌被删除时，相应的商品也会被删除
#     brand = models.ForeignKey('Brand', on_delete=models.CASCADE)
#     # 商品名称，商品名称
#     name = models.CharField(max_length=100)
#     # 商品价格，商品价格
#     price = models.DecimalField(max_digits=10, decimal_places=2)
#
#     def __str__(self):
#         return self.name
#
#
# # 商品分类表
# class Category(models.Model):
#     # 分类名称，作为主键使用，唯一标识每一个分类
#     name = models.CharField(max_length=100)
#     # 分类数量，表示该分类下有多少个商品
#     num = models.IntegerField()
#
#     def __str__(self):
#         return self.name
#
#
# # 商品品牌表
# class Brand(models.Model):
#     # 品牌ID，作为主键使用，唯一标识每一个品牌
#     name = models.CharField(max_length=100)
#     # 品牌卖出数量，表示该品牌卖出了多少个商品
#     num = models.IntegerField()
#
#     def __str__(self):
#         return self.name
#
#
# # 客户评论表
# class CustomerReview(models.Model):
#     # 评论ID，作为主键使用，唯一标识每一个评论
#     review_id = models.AutoField(primary_key=True)
#     # 评论关联的商品，外键关联到Product模型，CASCADE确保当关联的商品被删除时，相应的评论也会被删除
#     product = models.ForeignKey('Product', on_delete=models.CASCADE, related_name='reviews')
#     # 商品的好评率
#     rating = models.IntegerField()
#
#     def __str__(self):
#         return f"Review #{self.review_id} on {self.product.name}"
#     # def __str__(self):
#     #     return f"Review by {self.user_name} on {self.product.name}"
#
